package battlezone;

import java.io.*;
import java.net.*;

public class Network {
    private Model _model;
    private static final Configuration _configuration = Configuration.getInstance();
    private DatagramSocket _socket = null;
    private DatagramPacket[] _packets;
    
    public Network() {
        try {
            _socket = new DatagramSocket();
            
            //set up the packets once so that they don't have to be rebuilt every time a network signal is sent
            final InetAddress ips[] = _configuration.getIpAddresses();
            _packets = new DatagramPacket[ips.length];
            
            for (int i = 0; i < ips.length; i++) {
                final InetAddress ip = ips[i];
                _packets[i] = new DatagramPacket(new byte[0], 0, ip, _configuration.getPortNumber());
            }
        } catch (SocketException ex) {
            System.err.println(ex.getMessage());
        }
    }
    
    public void setModel(Model model) {
        if (_model != model) { //avoid an infinite loop
            _model = model;
            _model.setNetwork(this);
        }
        
        try {
            //launch the server
            Server server = new Server(_model);
            server.start();
        } catch (SocketException ex) {
            System.err.println(ex.getMessage());
        }
    }

    public void addPlayer(String id) {
        sendCommandToNetwork("ENTER " + id);
    }

    public void removeObject(String id) { //not used, objects are removed automatically for robustness
        sendCommandToNetwork("REMOVE " + id);
    }

    public void removePlayer(String id) {
        sendCommandToNetwork("LEAVE " + id);
    }

    public void killObject(String id) {
        sendCommandToNetwork("KILL " + id);
    }

    public void addObject(String id, BattlezoneObject object) {
        addObject(id, object, false);
    }
    public void addObject(String id, BattlezoneObject object, boolean playFireSound) {
        if (object.getClass() == Tank.class) {
            sendCommandToNetwork("ADD " + id + " tank-live");
        } else {
            if (playFireSound) {
                sendCommandToNetwork("ADD " + id + " projectile fire");
            } else {
                sendCommandToNetwork("ADD " + id + " projectile none");
            }
        }
        updateObjectPosition(id, object); //automatically send the object's position too
    }

    public void updateObjectPosition(String id, BattlezoneObject object) {
        sendCommandToNetwork("UPDATE " + id + ' ' + object.getPositionX() + ' ' + object.getPositionY() + ' ' + object.getAzimuth());
    }


    private void sendCommandToNetwork(final String command) {
        for (DatagramPacket packet : _packets) {
            packet.setData(command.getBytes());
            try {
                _socket.send(packet);
            } catch (IOException ex) {
                System.err.println(ex.getMessage());
            }
        }
    }
}